#pragma once
#include "DataStructure/Input/Element/CQUAD4Data.h"
#include "DataStructure/Input/Material/IsotropicMaterial.h"
#include "DataStructure/Input/Node/NodeData.h"
#include "DataStructure/Input/Property/PSHELLData.h"
#include "DataStructure/Input/Solver/DOFDirections.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/IService/Input/Element/IElementService.h"
#include "DBManager/IService/Input/Material/IIsotropicMaterialService.h"
#include "DBManager/IService/Input/Node/INodeService.h"
#include "DBManager/IService/Input/Property/IPSHELLService.h"

using SG::DataStructure::FEM::DOFDirections;
using namespace SG::DBManager;
extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

/// 单个四边形壳单元模型
class QuadShell_OneEle
{
  public:
    QuadShell_OneEle ()
    {
        DB_SERVICEFACTORY->ClearDatabase ();
        Input (DB_SERVICEFACTORY);
    }

    /// @brief 写入模型数据
    void               Input (const DBServiceFactorySP dbServiceFactory);
    DBServiceFactorySP GetModel ()
    {
        return DB_SERVICEFACTORY;
    }

  private:
    // DBServiceFactorySP m_dbServiceFactory;
};

void QuadShell_OneEle::Input (const DBServiceFactorySP dbServiceFactory)
{
    // 节点写入
    {
        SG::DataStructure::FEM::NodeData node;
        node.m_defCoord = 0;
        node.m_id       = 1;
        node.m_x[0]     = 0.0;
        node.m_x[1]     = 0.0;
        node.m_x[2]     = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 2;
        node.m_x[0] = 1.0;
        node.m_x[1] = 0.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 3;
        node.m_x[0] = 1.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
        node.m_id   = 4;
        node.m_x[0] = 0.0;
        node.m_x[1] = 1.0;
        node.m_x[2] = 0.0;
        dbServiceFactory->get<INodeService> ()->Add (node);
    }
    // 截面属性写入
    {
        SG::DataStructure::FEM::PSHELLData pShell;
        pShell.m_id         = 1;
        pShell.m_mId1       = 1;
        pShell.m_thickness  = 0.5;
        pShell.m_mId2       = 2;
        pShell.m_bendModify = 0.9;
        pShell.m_mId3       = 3;
        pShell.m_ts         = 2.0 / 3;
        pShell.m_mId4       = 0;
        // pShell.m_Z1, m_Z2;
        // pShell.m_NSM;
        dbServiceFactory->get<IPSHELLService> ()->Add (pShell);
    }

    // 写入材料
    {
        SG::DataStructure::FEM::IsotropicMaterial material;
        material.m_id = 1;
        material.m_E  = 2.0;   // 考虑到测试的有效数字问题
        material.m_nu = 0.3;
        material.m_G  = 5800;  // 用于Drill计算
        dbServiceFactory->get<IIsotropicMaterialService> ()->Add (material);

        SG::DataStructure::FEM::IsotropicMaterial material2;
        material2.m_id  = 2;
        material2.m_E   = 71708.0;
        material2.m_G   = 27235.3;
        material2.m_nu  = 0.33;
        material2.m_rho = 2.8 - 9;
        material2.m_A   = 21.1;
        dbServiceFactory->get<IIsotropicMaterialService> ()->Add (material2);

        SG::DataStructure::FEM::IsotropicMaterial material3;
        material3.m_id  = 3;
        material3.m_E   = 80327.0;
        material3.m_G   = 30338.0;
        material3.m_nu  = 0.31;
        material3.m_rho = 2.63 - 9;
        dbServiceFactory->get<IIsotropicMaterialService> ()->Add (material3);
    }

    // 写入单元
    {
        SG::DataStructure::FEM::CQUAD4Data ele;
        ele.m_id  = 1;  // 不确定
        ele.m_pId = 1;
        // ele.m_g.resize (4);
        ele.m_g[0] = 1;
        ele.m_g[1] = 2;
        ele.m_g[2] = 3;
        ele.m_g[3] = 4;
        dbServiceFactory->get<IElementService> ()->Add (ele);
    }

    // // 节点固定约束
    // {
    //     SG::DataStructure::FEM::SinglePointConstrain spc;
    //     spc.m_g = 1;
    //     spc.m_indexes = {DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz};
    //     spc.m_values = {0.0, 0.0, 0.0};
    //     dbServiceFactory -> get<SPCService>()->Add (spc);
    //     spc.m_g = 3;
    //     spc.m_indexes = {DOFDirections::DOF_Ux, DOFDirections::DOF_Uy, DOFDirections::DOF_Uz};
    //     spc.m_values = {0.0, 0.0, 0.0};
    //     dbServiceFactory -> get<SPCService>()->Add (spc);
    //     // 平面桁架，约束面外唯一自由度
    //     spc.m_g = 2;
    //     spc.m_indexes = {DOFDirections::DOF_Uz};
    //     spc.m_values = {0.0};
    //     dbServiceFactory -> get<SPCService>()->Add (spc);
    // }
}